package com.free.bsf.core.util;

import com.free.bsf.core.base.Callable;
import com.free.bsf.core.common.PropertyCache;
import lombok.val;
import org.apache.logging.log4j.util.Strings;
import org.springframework.core.env.AbstractEnvironment;
import org.springframework.core.env.EnumerablePropertySource;
import org.springframework.core.env.PropertySource;

/**
 * @author: chejiangyi
 * @version: 2019-06-15 10:04
 **/
public class PropertyUtils {
    public static String NULL="<?NULL?>";
//    public static void eachProperty(Callable.Action3<String,String,Object> call){
//        for(val key: System.getProperties().stringPropertyNames()){
//            call.invoke("properties",key,System.getProperty(key));
//        }
//        for(val kv: System.getenv().entrySet()){
//            call.invoke("env",kv.getKey(),kv.getValue());
//        }
//    }

    public static void eachProperty2(Callable.Action2<String,Object> call){
        val env = ContextUtils.getApplicationContext().getEnvironment();
        for (PropertySource<?> source : env.getPropertySources()) {
            PropertySource propertySource = source;
            //遍历每个配置来源中的配置项
            if (propertySource instanceof EnumerablePropertySource) {
                for (String name : ((EnumerablePropertySource) propertySource).getPropertyNames()) {
                    /*
                    由于每个配置来源可能配置了同一个配置项，存在相互覆盖的情况，为了保证获取到的值与通过@Value获取到的值一致，
                    需要通过env.getProperty(name)获取配置项的值。
                    */
                    call.invoke(name,env.getProperty(name));
                }
            }
        }

    }

    private static <T> T getProperty(String key,T defaultvalue) {
        String value = System.getProperty(key);
        if(value == null){
            value = System.getenv(key);
        }
        if(value == null && ContextUtils.getApplicationContext()!=null)
        {
            value = ContextUtils.getApplicationContext().getEnvironment().getProperty(key);
        }
        if(value == null)
        {
            return defaultvalue;
        }
        return (T) ConvertUtils.convert(value,defaultvalue.getClass());
    }

    public static Object getProperty(String key) {
        String value = System.getProperty(key);
        if(value == null){
            value = System.getenv(key);
        }
        if(value == null && ContextUtils.getApplicationContext()!=null)
        {
            value = ContextUtils.getApplicationContext().getEnvironment().getProperty(key);
        }
        return value;
    }

    public static <T> T getEnvProperty(String key,T defaultvalue){
        String value = System.getenv(key);
        if(value==null)
        {    return defaultvalue;}
        else
        {    return  (T) ConvertUtils.convert(value,defaultvalue.getClass());}
    }


    public static <T> T getSystemProperty(String key,T defaultvalue)
    {
        String value = System.getProperty(key);
        if(value==null)
        {    return defaultvalue;}
        else
        {    return  (T) ConvertUtils.convert(value,defaultvalue.getClass());}
    }

    public static void setDefaultInitProperty(Class cls,String module,String key,String propertyValue)
    {
        setDefaultInitProperty(cls,module,key,propertyValue,"");
    }

    public static void setDefaultInitProperty(Class cls,String module,String key,String propertyValue,String message){
        if(Strings.isEmpty(PropertyUtils.getPropertyCache(key,""))) {
            if (!Strings.isEmpty(propertyValue)) {
                System.setProperty(key, propertyValue);
                PropertyCache.Default.tryUpdateCache(key,propertyValue);
                LogUtils.info(cls, module, "设置" + key + "=" + propertyValue+" "+message);
            }
        }else{
            //修復apollo meta bug,谨慎测试
            if(Strings.isEmpty(getSystemProperty(key,""))){
                System.setProperty(key, PropertyUtils.getPropertyCache(key,""));
            }
        }
    }

    public static <T> T getPropertyCache(String key,T defaultvalue){
        return PropertyCache.Default.get(key,defaultvalue);
    }

}
